/**
 * 项目名称：tv   
 * 类名称：FileDownLoader   
 * 类描述：   
 * 创建人：Issac   
 * 创建时间：2011-7-9 下午11:13:18   
 * 修改人：Issac   
 * 修改时间：2011-7-9 下午11:13:18   
 * 修改备注：   
 * @version 
 */
package com.tv.crawler;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.omg.CORBA.Request;

import com.tv.tools.Configuration;



/**
 * @ClassName: FileDownLoader
 * @Description: TODO
 * @author issac2009@vip.qq.com
 * @date 2011-7-9 下午11:13:18
 */
public class FileDownLoader {
	/**
	 * 根据 url 和网页类型生成需要保存的网页的文件名 去除掉 url 中非文件名字符
	 */
	public  String getFileNameByUrl(String url,String contentType)
	{
		url=url.substring(7);//remove http://
		if(contentType.indexOf("html")!=-1)//text/html
		{
			url= url.replaceAll("[\\?/:*|<>\"]", "_")+".html";
			return url;
		}
		else//如application/pdf
		{
			return url.replaceAll("[\\?/:*|<>\"]", "_")+"."+ contentType.substring(contentType.lastIndexOf("/")+1);
		}	
	}

	/**
	 * 保存网页字节数组到本地文件 filePath 为要保存的文件的相对地址
	 */
	public void saveToLocal(byte[] data, String filePath) {
		try {
			DataOutputStream out = new DataOutputStream(new FileOutputStream(new File(filePath)));
			for (int i = 0; i < data.length; i++){
				out.write(data[i]);
			}
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/* 下载 url 指向的网页 */
	public String  downloadFile(String url)
	{
		  String filePath=null;
		  /* 1.生成 HttpClinet 对象并设置参数*/
		  HttpClient httpClient=new HttpClient();
		  //设置 Http 连接超时 5s
		  httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
		  
		  /*
		   * 封装相对路径
		   */
		  if(!url.startsWith("http://v.163.com/tvlist/")){
			  url = "http://v.163.com/tvlist/" + url;
		  }
		  
		  /*2.生成 GetMethod 对象并设置参数*/
		  GetMethod getMethod=new GetMethod(url);	 
		  
		 
		  
		  //设置 get 请求超时 5s
		  getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,5000);
		  //设置请求重试处理
		  getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,new DefaultHttpMethodRetryHandler());
		  
		  /*
		  String fileStr = Class.class.getClass().getResource("/").getPath();
		  Configuration rc = new Configuration(fileStr + "init.properties");
		  String path = rc.getValue("website.src.page");
		  */
		  InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("init.properties");   
		  Properties p = new Properties();   
		  try {   
			   p.load(inputStream);   
		  } catch (IOException e1) {   
			   e1.printStackTrace();   
		  }  
		  String path = p.getProperty("website.src.page");
		  
		  
		  /*3.执行 HTTP GET 请求*/
		  try{ 
			  	int statusCode = httpClient.executeMethod(getMethod);
			  	//判断访问的状态码
			  	if (statusCode != HttpStatus.SC_OK) 
			  	{
			  		System.err.println("Method failed: "+ getMethod.getStatusLine());
			  		filePath=null;
			  	}
			  
			  	/*4.处理 HTTP 响应内容, 内容过大，改成stream的方式*/
			  	InputStream responseBody = getMethod.getResponseBodyAsStream();
			  	
			  	//根据网页 url 生成保存时的文件名
			  	filePath=path+getFileNameByUrl(url, getMethod.getResponseHeader("Content-Type").getValue());
			  	
			  	saveToLocal(getBytesFromIS(responseBody),filePath);
			  	 System.out.println("网页保存成功!");
		  	} catch (HttpException e) {
				   // 发生致命的异常，可能是协议不对或者返回的内容有问题
				   System.out.println("Please check your provided http address!");
				   e.printStackTrace();
			} catch (IOException e) {
				   // 发生网络异常
				   e.printStackTrace();
			} finally {
				   // 释放连接
				   getMethod.releaseConnection();		   
			}
			return filePath;
	}
	
	/*
	 * 把inputstream 转成 byte[]
	 */
	public static byte[] getBytesFromIS(InputStream is) throws IOException{
	    ByteArrayOutputStream baos = new ByteArrayOutputStream();
	    int b=0;
	    while( (b = is.read())!=-1)
	        baos.write(b);
	    return baos.toByteArray();
	}

	// 测试的 main 方法
	public static void main(String[] args) {
		FileDownLoader downLoader = new FileDownLoader();
		downLoader.downloadFile("http://v.163.com/tvlist/index_21.html?tid=129");
	}
}
